using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;
using System.Collections.ObjectModel;
using Microsoft.Xna.Framework.Graphics;

namespace Evolution.Engine.Managers
{
    public class KeyList : Collection<Keys> { }

    public class InputManager : Singleton<InputManager>
    {
        private Point lastMouseLocation;
        private Vector2 mouseMoved;
        private KeyList keys = new KeyList();
        private int _ScrollWheelValue = 0;
        private int _LastScrollValue = 0;
        private bool _Dragging;
        private bool _MouseHandled;

        public bool MouseHandled { get { return _MouseHandled; } set { _MouseHandled = value; } }
        public bool Dragging { get { return _Dragging; } set { _Dragging = value; } }
        public int ScrollValue { get { return _LastScrollValue - _ScrollWheelValue; } }
        public Vector2 MouseMoved { get { return mouseMoved; } }
        public KeyList Keys { get { return keys; } }
        public KeyboardState KeyboardState { get { return Keyboard.GetState(); } }
        public Point LastMouseLocation { get { return lastMouseLocation; } set { lastMouseLocation = value; } }
        public Vector2 LastMouseLocationVector { get { return new Vector2(lastMouseLocation.X, lastMouseLocation.Y); } }
        public Vector2 CurrentMouseLocation { get { return new Vector2(CurrentState.X, CurrentState.Y); } }
        public Point CurrentMousePoint { get { return new Point(CurrentState.X, CurrentState.Y); } }
        public MouseState LastState = Mouse.GetState();
        public MouseState CurrentState = Mouse.GetState();

        private TimeSpan _TillDragging = new TimeSpan(0);

        public void Update(GameTime gameTime)
        {
            LastState = CurrentState;
            CurrentState = Mouse.GetState();

            _Dragging = false;

            if (LeftButtonDown() && _TillDragging.TotalMilliseconds <= 0)
                _TillDragging = new TimeSpan(500);

            if (_TillDragging.TotalMilliseconds > 0)
                _TillDragging -= new TimeSpan(50);

            if (LastState.LeftButton == ButtonState.Pressed && CurrentState.LeftButton == ButtonState.Pressed && _TillDragging.TotalMilliseconds <= 0)
            {
                _Dragging = true;
            }

            if (MouseManager.Instance.Current != "Content/GUI/Mouse/MousePointer" && !_Dragging)
            {
                MouseManager.Instance.SetMousePointer("Content/GUI/Mouse/MousePointer");
            }

            mouseMoved = new Vector2(
                lastMouseLocation.X - CurrentState.X,
                lastMouseLocation.Y - CurrentState.Y
            );

            lastMouseLocation = new Point(CurrentState.X, CurrentState.Y);
            _LastScrollValue = _ScrollWheelValue;

            _ScrollWheelValue = CurrentState.ScrollWheelValue;

            keys.Clear();
            foreach (Keys k in Keyboard.GetState().GetPressedKeys())
                Keys.Add(k);
        }

        public MouseButton GetButtonPressed()
        {
            if (CurrentState.LeftButton == ButtonState.Pressed) return MouseButton.Left;
            if (CurrentState.MiddleButton == ButtonState.Pressed) return MouseButton.Middle;
            if (CurrentState.RightButton == ButtonState.Pressed) return MouseButton.Right;
            return MouseButton.XButton1;
        }
        public MouseButton GetButtonReleased()
        {
            if (LeftButtonUp()) return MouseButton.Left;
            if (MiddleButtonUp()) return MouseButton.Middle;
            if (RightButtonUp()) return MouseButton.Right;

            return MouseButton.XButton1;
        }
        public bool MouseUp()
        {
            if (LeftButtonUp() || MiddleButtonUp() || RightButtonUp())
                return true;

            return false;
        }
        public bool MouseDown()
        {
            if (LeftButtonDown() || MiddleButtonDown() || RightButtonDown())
                return true;

            return false;
        }

        #region Button Presses

        public bool LeftButtonDown()
        {           
            if (CurrentState.LeftButton == ButtonState.Pressed)
                if (LastState.LeftButton == ButtonState.Released)
                    return true;

            return false;
        }

        public bool MiddleButtonDown()
        {
            return (CurrentState.MiddleButton == ButtonState.Pressed && LastState.MiddleButton == ButtonState.Released);
        }

        public bool RightButtonDown()
        {
            return (CurrentState.RightButton == ButtonState.Pressed && LastState.RightButton == ButtonState.Released);
        }

        public bool LeftButtonUp()
        {
            if (CurrentState.LeftButton == ButtonState.Released)
                if (LastState.LeftButton == ButtonState.Pressed)
                    return true;
            return false;
        }

        public bool MiddleButtonUp()
        {
            return (CurrentState.MiddleButton == ButtonState.Released && LastState.MiddleButton == ButtonState.Pressed);
        }

        public bool RightButtonUp()
        {
            return (CurrentState.RightButton == ButtonState.Released && LastState.RightButton == ButtonState.Pressed);
        }

        #endregion
    }
}
